package com.yokead.common.tools;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.CharsetUtil;
import cn.jiangzeyin.StringUtil;
import cn.jiangzeyin.common.spring.SpringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import com.yokead.service.domain.DoMainServer;
import com.yokead.system.log.SystemLog;
import com.yokead.util.EncryptUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Created by jiangzeyin on 2017/5/11.
 * <p>
 * 扫描所有信息
 */
public class AllUrl {

    public static JSONArray start(String confPath, String url) throws IOException {
        File file = new File(confPath);
        File[] files = getConf(file, true);
        JSONArray jsonArray = new JSONArray();
        for (File item : files) {
            if (item.isDirectory()) {
                File[] childs = getConf(item, false);
                for (File item2 : childs) {
                    JSONArray objects = scannerFile(item2, url);
                    if (objects != null) {
                        jsonArray.addAll(objects);
                    }
                }
            } else {
                JSONArray objects = scannerFile(item, url);
                if (objects != null) {
                    jsonArray.addAll(objects);
                }
            }
        }
        return jsonArray;
    }

    public static JSONArray start(String confPath) throws IOException {
        return start(confPath, null);
    }

    private static JSONArray scannerFile(File file, String url) throws IOException {
        NgxConfig conf = NgxConfig.read(file.getPath());
        List<NgxEntry> locations = conf.findAll(NgxConfig.BLOCK, "server", "location");
        NgxParam server_name = conf.findParam("server", "server_name");
        List<String> stringList = server_name.getValues();
        DoMainServer doMainServer = SpringUtil.getBean(DoMainServer.class);
        List<String> allUrl = doMainServer.listAll();
        if (stringList == null) {
            return null;
        }
        if (allUrl == null) {
            return null;
        }
        JSONArray jsonArray = new JSONArray();
        // boolean r = stringList.size() > 1;
        for (String rootUrl : stringList) {
            if (url != null) {
                if (!url.equals(rootUrl)) {
                    continue;
                }
            }
            boolean find = false;
            for (String canUrl : allUrl) {
                if (rootUrl.endsWith(canUrl)) {
                    find = true;
                    break;
                }
            }
            if (!find) {
                continue;
            }
            JSONArray jsonArray_ = scannerUrl(rootUrl, locations);
            if (jsonArray_ != null) {
                jsonArray.addAll(jsonArray_);
            }
        }
        return jsonArray;
    }

    private static JSONArray scannerUrl(String rootUrl, List<NgxEntry> locations) {
        if (locations == null) {
            return null;
        }
        JSONArray jsonArray = new JSONArray();
        for (NgxEntry ngxEntry : locations) {
            if (ngxEntry instanceof NgxBlock) {
                NgxBlock block = (NgxBlock) ngxEntry;
                NgxParam root = block.findParam("root");
                if (root != null) {
                    List<String> rootValues = block.getValues();
                    if (rootValues.size() == 1) {
                        JSONArray fileArray = scannerDir(rootUrl, root.getValue(), root.getValue());
                        if (fileArray != null) {
                            jsonArray.addAll(fileArray);
                        }
                    }
                }
                NgxParam rewrite = block.findParam("rewrite");
                if (rewrite != null) {
                    List<String> values = rewrite.getValues();
                    if (values.size() == 3) {
                        String url = values.get(1);
                        if (url.endsWith("$2")) {
                            url = url.substring(0, url.length() - 2);
                        }
                        String locUrl = rootUrl + block.getValue();
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("url", locUrl);
                        jsonObject.put("toUrl", url);
                        jsonObject.put("type", "rewrite");
                        jsonArray.add(jsonObject);
                        //System.out.println(locUrl + "  " + url);
                    }
                    //System.out.println(values.size());
                }
                NgxParam proxy_pass = block.findParam("proxy_pass");
                if (proxy_pass != null) {
                    String url = rootUrl + block.getValue();
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("url", url);
                    jsonObject.put("type", "proxy");
                    jsonArray.add(jsonObject);
                }
            }
        }
        return jsonArray;
    }

    private static JSONArray scannerDir(String rootUrl, String root, String path) {
        File file = new File(path);
        if (!file.exists()) {
            return null;
        }
        JSONArray array = new JSONArray();
        File[] files = file.listFiles((dir, name) -> {
            File temp = new File(dir, name);
            if (temp.isDirectory()) {
                return true;
            }
            return name.endsWith(".html");
        });
        for (File item : files != null ? files : new File[0]) {
            if (item.isDirectory()) {
                JSONArray jsonArray = scannerDir(rootUrl, root, item.getPath());
                if (jsonArray != null) {
                    array.addAll(jsonArray);
                }
            } else {
                String name = item.getName();
                if (name.equals("index.html")) {
                    String url = StringUtil.clearPath(rootUrl + "/" + StringUtil.clearPath(item.getPath()).replace(root, ""));
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type", "file");
                    File shFile = new File(item.getParent(), "index_sh.html");
                    File tfFile = new File(item.getParent(), "index_tf.html");
                    if (shFile.exists() || tfFile.exists()) {
                        jsonObject.put("status", shFile.exists() ? "tf" : tfFile.exists() ? "sh" : null);
                        String uPath = null;
                        try {
                            uPath = EncryptUtil.encrypt(StringUtil.clearPath(item.getParent()));
                        } catch (Exception e) {
                            SystemLog.ERROR().error("读取错误", e);
                        }
                        jsonObject.put("urlPath", uPath);
                    }
                    try {
                        String weixin = FileUtil.readString(item, CharsetUtil.CHARSET_UTF_8);
                        if (!StringUtil.isEmpty(weixin)) {
                            int s = weixin.indexOf("<!--weixin-->");
                            int e = weixin.indexOf("<!--weixin_end-->");
                            if (e > s) {
                                String v = weixin.substring(s, e);
                                jsonObject.put("weixin", true);
                                String weixinPath = null;
                                try {
                                    weixinPath = EncryptUtil.encrypt(StringUtil.clearPath(item.getPath()));
                                } catch (Exception e1) {
                                    SystemLog.ERROR().error("读取错误", e);
                                }
                                jsonObject.put("weixinPath", weixinPath);
                            }
                        }
                    } catch (IORuntimeException e) {
                        SystemLog.ERROR().error("读取错误", e);
                    }
                    jsonObject.put("url", url);
                    array.add(jsonObject);
                }
            }
        }
        return array;
    }

    private static File[] getConf(File file, boolean child) {
        return file.listFiles((dir, name) -> name.endsWith(".conf") || child && new File(dir, name).isDirectory());
    }
}
